﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using DataAccessLayer;

namespace BusinessLayer
{
    /// <summary>
    /// The park.
    /// </summary>
    public class Park : BusinessEntity
    {
        /// <summary>
        /// The park repository.
        /// </summary>
        public class ParkRepository : Repository<Park>
        {
            
        }

        /// <summary>
        /// The park repository.
        /// </summary>
        public static ParkRepository Repository = new ParkRepository();

        /// <summary>
        /// Gets the name.
        /// </summary>
        public string Name
        {
            get { return (string)this.Get("Name"); }
            set { this.Set("Name", value); }
        }

        /// <summary>
        /// Gets the id.
        /// </summary>
        public int Id
        {
            get { return (int)this.Get("Id"); }
        }

        /// <summary>
        /// Gets the location.
        /// </summary>
        public Polygon Location
        {
            get
            {
                var pts = new List<Point>();
                Reader<ParkPoint> reader = ParkPoint.Repository.ReadAll(this.Id);
                while (reader.Read())
                    pts.Add(new Point(reader.Current.X, reader.Current.Y));
                reader.Close();
                return new Polygon(pts);
            }
            set
            {
                ParkPoint.Repository.Remove(this.Id);
                for (int i = 0; i < value.Points.Count; i++)
                {
                    ParkPoint parkPoint = ParkPoint.Repository.Create();
                    parkPoint.ParkId = this.Id;
                    parkPoint.Index = i;
                    parkPoint.X = value.Points[i].X;
                    parkPoint.Y = value.Points[i].Y;
                    parkPoint.Save();
                }
            }
        }

        /// <summary>
        /// Gets the number of slots.
        /// </summary>
        public int NumberOfSlots
        {
            get { return (int)this.Get("NumberOfSlots"); }
            set { this.Set("NumberOfSlots", value); }
        }

        /// <summary>
        /// Gets the number of available slots.
        /// </summary>
        public int NumberOfAvailableSlots
        {
            get { return (int)this.Get("NumberOfAvailableSlots"); }
            set { this.Set("NumberOfAvailableSlots", value); }
        }


        /// <summary>
        /// Initializes a new instance of the <see cref="Park"/> class.
        /// </summary>
        internal Park(Dictionary<string, object> park)
        {
            this.Initialize(park);
        }

        /// <summary>
        /// Default constructor.
        /// Must call Initialize method before using.
        /// </summary>
        public Park()
        {
        }

        /// <summary>
        /// Save the park.
        /// </summary>
        public override void Save()
        {
            Park.Repository.Write(this);
        }

        /// <summary>
        /// Is the car in the park.
        /// </summary>
        public bool CarInPark(Car car)
        {
            return this.Location.Contains(car.CurrentState().Location);
        }

        /// <summary>
        /// Cars in park.
        /// </summary>
        public List<Car> CarsInPark()
        {
            List<Car> cars = new List<Car>();
            Reader<Car> reader = Car.Repository.ReadAll();
            while (reader.Read())
            {
                if(CarInPark(reader.Current))
                    cars.Add(reader.Current);
            }
            reader.Close();
            return cars;
        }
    }
}
